#include "CVector3.h"

/////////////////////////////////////// CROSS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This returns a perpendicular vector from 2 given vectors by taking the cross product.
/////
/////////////////////////////////////// CROSS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

CVector3 CVector3::Cross(CVector3 vVector1, CVector3 vVector2)
{
	CVector3 vNormal;									// The vector to hold the cross product

	// If we are given 2 vectors (the view and up vector) then we have a plane define.
	// The cross product finds a vector that is perpendicular to that plane,
	// which means its point is straight out of the plane at a 90 degree angle.
	// The equation for the cross product is simple, but difficult at first to memorize:

	// The X value for the vector is:  (V1.y * V2.z) - (V1.z * V2.y)													// Get the X value
	vNormal.x = ((vVector1.y * vVector2.z) - (vVector1.z * vVector2.y));

	// The Y value for the vector is:  (V1.z * V2.x) - (V1.x * V2.z)
	vNormal.y = ((vVector1.z * vVector2.x) - (vVector1.x * vVector2.z));

	// The Z value for the vector is:  (V1.x * V2.y) - (V1.y * V2.x)
	vNormal.z = ((vVector1.x * vVector2.y) - (vVector1.y * vVector2.x));

	// *IMPORTANT* This is not communitive. You can not change the order of this or
	// else it won't work correctly.  It has to be exactly like that.  Just remember,
	// If you are trying to find the X, you don't use the X value of the 2 vectors, and
	// it's the same for the Y and Z.  You notice you use the other 2, but never that axis.
	// If you look at the camera rotation tutorial, you will notice it's the same for rotations.

	// So why do I need the cross product to do a first person view?  Well, we need
	// to find the axis that our view has to rotate around.  Rotating the camera left
	// and right is simple, the axis is always (0, 1, 0).  Rotating around the camera
	// up and down is different because we are constantly going in and out of axises.
	// We need to find the axis that our camera is on, and that is why we use the cross
	// product.  By taking the cross product between our view vector and up vector,
	// we get a perpendicular vector to those 2 vectors, which is our desired axis.
	// Pick up a linear algebra book if you don't already have one, you'll need it.

	// Return the cross product
	return vNormal;
}


/////////////////////////////////////// MAGNITUDE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This returns the magnitude of a vector
/////
/////////////////////////////////////// MAGNITUDE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

float CVector3::Magnitude(CVector3 vNormal)
{
	// This will give us the magnitude or "norm" as some say, of our normal.
	// The magnitude has to do with the length of the vector.  We use this
	// information to normalize a vector, which gives it a length of 1.
	// Here is the equation:  magnitude = sqrt(V.x^2 + V.y^2 + V.z^2)   Where V is the vector

	return (float)sqrt( (vNormal.x * vNormal.x) +
						(vNormal.y * vNormal.y) +
						(vNormal.z * vNormal.z) );
}


/////////////////////////////////////// NORMALIZE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This returns a normalize vector (A vector exactly of length 1)
/////
/////////////////////////////////////// NORMALIZE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

CVector3 CVector3::Normalize(CVector3 vVector)
{
	// What's this function for you might ask?  Well, since we are using the cross
	// product formula, we need to make sure our view vector is normalized.
	// For a vector to be normalized, it means that it has a length of 1.
	// For instance, a vector (2, 0, 0) would be (1, 0, 0) once normalized.
	// Most equations work well with normalized vectors.  If in doubt, normalize.

	// Get the magnitude of our normal
	float magnitude = Magnitude(vVector);

	// Now that we have the magnitude, we can divide our vector by that magnitude.
	// That will make our vector a total length of 1.
	// This makes it easier to work with too.
	vVector = vVector / magnitude;

	// Finally, return our normalized vector
	return vVector;
}

CVector3 CVector3::Create(CVector3 vPoint1, CVector3 vPoint2)
{
    CVector3 vCreatedFromPoints;									// The new vector
    vCreatedFromPoints.x = vPoint2.x - vPoint1.x;
    vCreatedFromPoints.y = vPoint2.y - vPoint1.y;
    vCreatedFromPoints.z = vPoint2.z - vPoint1.z;
    vCreatedFromPoints = Normalize(vCreatedFromPoints);
    return vCreatedFromPoints;
}
